﻿using Com.JunCaiSoft.API.Common.AssistClass;
using Com.JunCaiSoft.API.WXWork.Dto;
using Com.JunCaiSoft.Common.AssistClass;
using Com.JunCaiSoft.Common.Extension;
using Com.JunCaiSoft.SystemConfig.IDao;
using Com.JunCaiSoft.WXWork.Common;
using Com.JunCaiSoft.WXWork.Dto;
using Com.JunCaiSoft.WXWork.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Com.JunCaiSoft.API.WXWork.Controllers
{
    /// <summary>
    /// 企业微信通讯录
    /// </summary>
    [Route("api/WXWork/[controller]/[action]")]
    [ApiController]
    //[Authorize]
    [AllowAnonymous]
    public class AddressBookController : Controller
    {
        /// <summary>
        /// 配置
        /// </summary>
        private IConfiguration Configuration { get; set; }
        /// <summary>
        /// 配置环境
        /// </summary>
        private readonly IWebHostEnvironment HostingEnvironment;
        /// <summary>
        /// BaseURL
        /// </summary>
        private readonly String BaseURL;
        /// <summary>
        /// AccessTokenURL
        /// </summary>
        private readonly String AccessTokenURL;
        /// <summary>
        /// AppSecretManager
        /// </summary>
        private readonly IAppSecretManageDao AppSecretManageDao;
        /// <summary>
        /// 微信通讯录接口构造函数
        /// </summary>
        /// <param name="env"></param>
        /// <param name="appSecretManageDao"></param>
        public AddressBookController(IWebHostEnvironment env,IAppSecretManageDao appSecretManageDao)
        {
            var builder = new ConfigurationBuilder()
                               .SetBasePath(env.ContentRootPath)
                               .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                               .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
                               .AddJsonFile("DataBaseExcute.json", optional: true, reloadOnChange: true);
            HostingEnvironment = env;
            Configuration = builder.Build();
            BaseURL = Configuration.GetSection("WXWork:BaseURL").Value;
            AccessTokenURL = BaseURL + Configuration.GetSection("WXWork:AccessTokenURL").Value;
            AppSecretManageDao = appSecretManageDao;
        }
        /// <summary>
        /// 获取所有部门
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> GetAllPartment(Boolean IsRefresh = false)
        {
            var deptlist = RedisCacheExtension.GetStringValue("PartmentList");

            if (String.IsNullOrEmpty(deptlist) || IsRefresh)
            {
                var deptList = await GetPartmentListAsync();

                deptlist = JsonConvert.SerializeObject(deptList.department);
            }

            return await Task.Run(() => Content(deptlist));
        }
        /// <summary>
        /// 获取所有成员列表
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> SimpleMemberList(Int32 DeptId = 1,Int32 IsContainChildren = 1,Boolean IsRefresh = false)
        {
            var memberlist = RedisCacheExtension.GetStringValue("DeptMemberList");

            if (String.IsNullOrEmpty(memberlist) || IsRefresh)
            {
                var memberList = await MemberListStorageAsync<Employer>(DeptId, IsContainChildren);

                memberlist = JsonConvert.SerializeObject(memberList.userlist);
            }

            return await Task.Run(() => Content(memberlist));
        }
        /// <summary>
        /// 获取所有成员详细信息列表
        /// </summary>
        /// <param name="DeptId"></param>
        /// <param name="IsContainChildren"></param>
        /// <param name="IsRefresh"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> MemberDetailList(Int32 DeptId = 1, Int32 IsContainChildren = 1, Boolean IsRefresh = false)
        {
            var memberlist = RedisCacheExtension.GetStringValue("DeptMemberDetailList");

            if (String.IsNullOrEmpty(memberlist) || IsRefresh)
            {
                var memberList = await MemberListStorageAsync<EmployerDetail>(DeptId, IsContainChildren);

                memberlist = JsonConvert.SerializeObject(memberList.userlist);
            }

            return await Task.Run(() => Content(memberlist));
        }
        /// <summary>
        /// 返回一颗部门员工树（用于查找Tree）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> GetMemberTree(Int32 DeptId = 1, Int32 IsContainChildren = 1, Boolean IsRefresh = false,String keyword = null)
        {
            var deptlist = RedisCacheExtension.GetStringValue("PartmentList");

            if (String.IsNullOrEmpty(deptlist) || IsRefresh)
            {
                var deptList = await GetPartmentListAsync();

                deptlist = JsonConvert.SerializeObject(deptList.department);
            }

            var depts = JsonConvert.DeserializeObject<List<Department>>(deptlist).OrderBy(x => x.id).ToList();

            //if (!String.IsNullOrEmpty(keyword))
            //{
            //    depts = depts.Where(x => x.name.Contains(keyword)).ToList();
            //}

            var memberlist = RedisCacheExtension.GetStringValue("DeptMemberList");

            if (String.IsNullOrEmpty(memberlist) || IsRefresh)
            {
                var memberList = await  MemberListStorageAsync<Employer>(DeptId, IsContainChildren);

                memberlist = JsonConvert.SerializeObject(memberList.userlist);
            }

            var members = JsonConvert.DeserializeObject<List<Employer>>(memberlist);

            if (!String.IsNullOrEmpty(keyword))
            {
                members = members.Where(x => x.name.Contains(keyword)).ToList();

                depts.ForEach(item => item.children = members.Where(x => x.department.Contains(item.id)).ToList());

                depts = depts.Where(x => x.children.Count != 0 || x.parentid == 0).ToList();
            }

            var rootDept = depts.Where(x => x.id == 1 && x.parentid == 0).FirstOrDefault();

            var root = new TreeNode() { 
                title = rootDept.name,
                partmentId = rootDept.id,
                expand = true
            };

            GetDepartmentTree(root, depts,members,keyword);

            var result = new List<TreeNode>();

            result.Add(root);

            return await Task.Run(() => Content(JsonConvert.SerializeObject(result)));
        }
        /// <summary>
        /// 返回一颗部门树（用于查找Tree）
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> GetPartmentTree(Int32 DeptId = 1, Int32 IsContainChildren = 1, Boolean IsRefresh = false, String keyword = null)
        {
            var deptlist = RedisCacheExtension.GetStringValue("PartmentList");

            if (String.IsNullOrEmpty(deptlist) || IsRefresh)
            {
                var deptList = await GetPartmentListAsync();

                deptlist = JsonConvert.SerializeObject(deptList.department);
            }

            var depts = JsonConvert.DeserializeObject<List<Department>>(deptlist).OrderBy(x => x.id).ToList();

            //if (!String.IsNullOrEmpty(keyword))
            //{
            //    depts = depts.Where(x => x.name.Contains(keyword)).ToList();
            //}


            if (!String.IsNullOrEmpty(keyword))
            {
                depts = depts.Where(x => x.name.Contains(keyword)).ToList();

                depts.ForEach(x => x.parentid = 1);
            }

            var rootDept = depts.Where(x => x.id == 1 && x.parentid == 0).FirstOrDefault();

            var root = rootDept != null ? new TreeNode()
            {
                title = rootDept.name,
                partmentId = rootDept.id,
                expand = true
            } : new TreeNode() {
                title = "祥生建设",
                partmentId = 1,
                expand = true
            } ;

            GetDepartmentTree(root, depts, new List<Employer>(), keyword);

            var result = new List<TreeNode>();

            result.Add(root);

            return await Task.Run(() => Content(JsonConvert.SerializeObject(result)));
        }
        private TreeNode GetDepartmentTree(TreeNode node,List<Department> deptlist,List<Employer> members,String keyword)
        {
            if(node.children == null)
            {
                node.children = new List<TreeNode>();
            }

            deptlist.ForEach(item =>
            {
                if(item.parentid == node.partmentId && String.IsNullOrEmpty(node.userid))
                {
                    node.children.Add(new TreeNode()
                    {
                        partmentId = item.id,
                        title = item.name,
                        ordernum = item.order,
                        expand = !String.IsNullOrEmpty(keyword)
                    });
                }
            });

            node.children = node.children.OrderByDescending(x => x.ordernum).ToList();

            members.ForEach(member =>
            {
                if (member.department.Contains(node.partmentId))
                {
                    node.children.Add(new TreeNode()
                    {
                        userid = member.userid,
                        title = member.name,
                        ordernum = 999999999,
                        expand = !String.IsNullOrEmpty(keyword)
                    });
                }
            });

            if (node.children.Count == 0)
            {
                return node;
            }

            node.children.ForEach(item => {
                GetDepartmentTree(item, deptlist, members,keyword);
            });

            return node;
        }
        /// <summary>
        /// 通过员工ID获取员工信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> GetMemberById(String Id)
        {
            var member = (await MemberListStorageAsync<Employer>(1, 1)).userlist.Where(x => x.userid == Id).FirstOrDefault();

            return await Task.Run(() => Content(JsonConvert.SerializeObject(member)));
        }
        /// <summary>
        /// 通过员工ID获取员工详细信息
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet]
        public virtual async Task<ActionResult> GetMemberDetailById(String Id)
        {
            var member = (await MemberListStorageAsync<EmployerDetail>(1, 1)).userlist.Where(x => x.userid == Id).FirstOrDefault();

            return await Task.Run(() => Content(JsonConvert.SerializeObject(member)));
        }
        /// <summary>
        /// 从企业微信获取员工列表
        /// </summary>
        /// <param name="DeptId"></param>
        /// <param name="IsContainChildren"></param>
        /// <param name="IsSimple">是否Simple列表</param>
        /// <returns></returns>
        private async Task<EmployerList<T>> MemberListStorageAsync<T>(Int32 DeptId = 1, Int32 IsContainChildren = 1,Boolean IsSimple = true)
        {
            var token = RedisCacheExtension.GetStringValue(PartmentEnum.人力行政中心.ToString());

            if (String.IsNullOrEmpty(token))
            {
                var appkey = await AppSecretManageDao.AppKeyAsync("人力行政中心");
                var corpsecret = await AppSecretManageDao.AppSecretManagerAsync("人力行政中心");
                var accesstoken = WXWorkAccessToken.GetAccessToken(AccessTokenURL, appkey, corpsecret);
                RedisCacheExtension.SetStringValue(PartmentEnum.人力行政中心.ToString(), accesstoken.access_token, accesstoken.expires_in / 3600);
                token = accesstoken.access_token;
            }

            var partmentURL = BaseURL + (IsSimple ? Configuration.GetSection("WXWork:DeptMemberListAPI").Value : Configuration.GetSection("WXWork:DeptMemberDetailListAPI").Value) + "?access_token=" + token + "&department_id=" + DeptId + "&fetch_child=" + IsContainChildren;
            var memberList = JsonConvert.DeserializeObject<EmployerList<T>>(HttpExtension.HttpGet(partmentURL, true, "application/json;"));

            if (memberList.errcode == 0 && memberList.userlist != null)
            {
                RedisCacheExtension.Replace("DeptMemberList", JsonConvert.SerializeObject(memberList.userlist));
            }

            return memberList;
        }
        private async Task<DeptList> GetPartmentListAsync()
        {
            var token = RedisCacheExtension.GetStringValue(PartmentEnum.人力行政中心.ToString());

            if (String.IsNullOrEmpty(token))
            {
                var appkey = await AppSecretManageDao.AppKeyAsync("人力行政中心");
                var corpsecret = await AppSecretManageDao.AppSecretManagerAsync("人力行政中心");
                var accesstoken = WXWorkAccessToken.GetAccessToken(AccessTokenURL, appkey, corpsecret);
                RedisCacheExtension.SetStringValue(PartmentEnum.人力行政中心.ToString(), accesstoken.access_token, accesstoken.expires_in / 3600);
                token = accesstoken.access_token;
            }

            var partmentURL = BaseURL + Configuration.GetSection("WXWork:PartmentListAPI").Value + "?access_token=" + token;
            var deptList = JsonConvert.DeserializeObject<DeptList>(HttpExtension.HttpGet(partmentURL, true, "application/json;"));

            if (deptList.errcode == 0)
            {
                RedisCacheExtension.Replace("PartmentList", JsonConvert.SerializeObject(deptList.department));
            }

            return deptList;
        }
    }
}
